package model;

import java.util.Collection;

import persistency.controller.RegistrationController;
import util.Date;
import controller.ConfigurationController;

/**
 * Registration.java
 * Purpose: this class represents a registration to a course offered by the school
 * 
 * @author Hans Brems
 * @version 1.0 03/11/2011
 */

public class Registration implements  Cloneable, Comparable<Registration> ,RegistrationValidationBehavior,Observer ,Business {
	
	private OfferedCourse offeredCourse;
	private Date registrationDate; 
	private Student student;
	private int id;
	
	
	
	private boolean receiveCourseEmail = false;
	
	public Registration(){}

	/** Constructs a registration object */
	public Registration(int id,OfferedCourse offeredCourse, Student student , Date registrationDate) {
		this.offeredCourse = offeredCourse;
		this.registrationDate = registrationDate;
		this.student = student;
		this.id = id;
		
	}
	
	/** Returns the course which is being offered **/
	public OfferedCourse getOfferedCourse() {
		return offeredCourse;
	}

	/** Sets the course which is being offered **/
	public void setOfferedCourse(OfferedCourse offeredCourse) {
		this.offeredCourse = offeredCourse;
	}

	/** Returns the student which is being registered for the course **/
	public Student getStudent() {
		return student;
	}

	/** Sets the student which is being registered for the course **/
	public void setStudent(Student student) {
		this.student = student;
	}

	/** Returns the registrationDate **/
	public Date getRegistrationDate() {
		return registrationDate;
	}

	/** Sets the date of the registration **/
	public void setRegistrationDate(Date registrationDate) {
		this.registrationDate = registrationDate;
	}
	
	/** Checks for equality with another object **/
	@Override
	public boolean equals(Object object) {
		
		Registration otherRegistration;
		
		// Check for same reference
		if (this == object) {
			return true;
		}
		
		// Check if object type is equal
		if (object == null || object.getClass() != this.getClass()) {
			return false;
		}
		
		// Cast object to correct class
		otherRegistration = (Registration)object;
		
		// Check if object properties are equal
		return otherRegistration.getId() == getId();
	}
	
	
	
	public boolean isReceiveCourseEmail() {
		return receiveCourseEmail;
	}

	public void setReceiveCourseEmail(boolean receiveCourseEmail) {
		if(receiveCourseEmail){
			offeredCourse.registerForCourseEmail(this);
		}else{
			offeredCourse.unRegisterForCourseEmail(this);
		}
		this.receiveCourseEmail = receiveCourseEmail;
	}

	/** Returns a string representation of the object **/
	@Override
	public String toString() {
		return String.format("%s (%s)", (student != null)?student.getName(): "" , this.registrationDate);
	}

	/** Clones the object **/
	@Override
	public Object clone() throws CloneNotSupportedException {
		
		// Copy parent
		Registration clone = (Registration)super.clone();
		
		// Set properties
		clone.offeredCourse = this.offeredCourse;
		clone.registrationDate = this.registrationDate;
		clone.student = this.student;
		
		// Return result
		return clone;
	}	

	/** Compares the object to another object **/
	public int compareTo(Registration registration) {
		return this.toString().compareTo(registration.toString());
	}

	
	
	public void performValidate() throws Exception{
		RegistrationValidationBehavior rvb = RegistrationValidationBehaviorFactory.instance().getRegistrationValidationBehavior(this);
		rvb.validate(this);
	}
	
	@Override
	public void validate(Registration registration)throws Exception{
		//check if there are no overlaps in the schedule
		Collection<Registration> studentRegistrations = RegistrationController.instance().getByStudentIdRegistrations(student.getStudentNumber());
		for(Registration reg : studentRegistrations){
			if(reg.getOfferedCourse().getTimeBlock().overlaps(offeredCourse.getTimeBlock())){
				throw new Exception("There is already a class "+ reg.getOfferedCourse()+ " scheduled for " + student + " at " + offeredCourse.getTimeBlock());
			}
		}
		//check if there is still room in the class
		if(RegistrationController.instance().getByOfferedCourseIdRegistrations(offeredCourse.getId()).size() >= offeredCourse.getNumberOfPlaces()){
			throw new Exception("No more room in : " + offeredCourse);
		}
		
	}

	@Override
	public void sendEmail(String message) {
		System.out.println("sending email to " + student.getName().replaceFirst(" ", ".").replaceAll(" ", "")+"@ace.groept.be");
		System.out.println(ConfigurationController.instance().getProperty(message,student.getName(), offeredCourse.toString(),((Float)student.getsubmissionFee()).toString()));
		
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}
	
	
	
	
}